﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace 无线接收上位机
{
    public partial class Form1 : Form
    {
        bool busy = false;
        bool close = false;
        double now = 0;
        private byte err_level;
        private int RPM;
        private int Torq;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox2.Text = "115200";
            comboBox3.Text = "1";
            comboBox4.Text = "8";
            comboBox5.Text = "无";
            SearchAndAddSerialToComBox(serialPort1, comboBox1);
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            
        }
        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (close == true)                                  //是否正在关闭串口
                return;
            busy = true;                                        //正在接受串口数据
            int length = serialPort1.BytesToRead;               //串口缓冲区字节数
            byte[] rec = new byte[length];                      
            serialPort1.Read(rec, 0, length);                   //将串口缓冲器中数据读取到rec数组中
            serialPort1.DiscardInBuffer();                      //丢弃串口缓冲区中的数据
            if (length != 10)                                   //检验接收的字节数是否等于串口协议帧长度
            {
                busy = false;
                return;
            }
            byte sum = (byte)(rec[2] + rec[3] + rec[4] + rec[5] + rec[6] + rec[7] + rec[8]);//无线数据求和运算
            if (rec[0] == 0xFF && rec[1] == 0xAA && rec[9] == sum)  //检验协议帧包头是否为0xFFAA，并检查和运算是否相等
            {
                if (rec[2] == 0x01)                                             //周期为10ms的无线数据
                {
                    RPM = (rec[3] << 8) + rec[4];                               //计算电机转速
                    gaugeAngular1.Value = RPM;                                  //指针仪表控件动态刷新
                    Torq = (rec[5]<<8)+rec[6];                                  //计算电机扭矩
                    now = getTime();                                            //获得当前时间,精确到ms
                    try
                    {
                        plot1.Channels.Trace["Channel 1"].AddXY(now, RPM);      //电机转速曲线绘制
                        plot1.Channels.Trace["Channel 2"].AddXY(now, Torq);     //电机扭矩曲线绘制
                        plot1.Channels.Trace["Channel 3"].AddXY(now, rec[7]);   //电机功率曲线绘制
                        plot1.Channels.Trace["Channel 4"].AddXY(now, rec[8]);   //油门开度曲线绘制
                    }
                    catch { }
                    label28.Text = Convert.ToString(rec[8]);            //更新油门开度数码管控件                                       
                }
                else if(rec[2] == 0x02)
                {
                    thermometer4.Value = rec[3];                        //更新VCU温度
                    thermometer3.Value = rec[4];                        //更新电机温度
                    sevenSegmentInteger3.Value = rec[5];                //更新电池电流
                    sevenSegmentInteger2.Value = (rec[6] << 8) + rec[7];//更新母线电压
                    if ((rec[8] & 0x80) == 0x80)                        //更新电池状态
                    {
                        led3.Value = true;
                        led3.Indicator.Text = "正常";
                    }
                    else
                    {
                        led3.Value = false;
                        led3.Indicator.Text = "关机";
                    }

                    if ((rec[8] & 0x40) == 0x40)                        //电机状态
                    {
                        led2.Value = true;
                        led2.Indicator.Text = "使能";
                    }
                    else
                    {
                        led2.Value = false;
                        led2.Indicator.Text = "失能";
                    }

                    if ((rec[8] & 0x40) == 0x40)                        //电机状态
                    {
                        led2.Value = true;
                        led2.Indicator.Text = "使能";
                    }
                    else
                    {
                        led2.Value = false;
                        led2.Indicator.Text = "失能";
                    }
                    if ((rec[8] & 0x20) == 0x20)                        //待驶状态
                    {
                        led4.Value = true;
                        led4.Indicator.Text = "待驶";
                    }
                    else
                    {
                        led4.Value = false;
                        led4.Indicator.Text = "等待";
                    }
                    if ((rec[8] & 0x10) == 0x10)                        //冷却系统
                    {
                        led5.Value = true;
                        led5.Indicator.Text = "打开";
                    }
                    else
                    {
                        led5.Value = false;
                        led5.Indicator.Text = "关闭";
                    }
                    if ((rec[8] & 0x08) == 0x08)                        //行驶模式
                    {
                        led6.Value = true;
                        led6.Indicator.Text = "耐久";
                    }
                    else
                    {
                        led6.Value = false;
                        led6.Indicator.Text = "直线";
                    }
                    if ((rec[8] & 0x04) == 0x04)                        //制动系统
                    {
                        led7.Value = true;
                        led7.Indicator.Text = "制动";
                    }
                    else
                    {
                        led7.Value = false;
                        led7.Indicator.Text = "前进";
                    }
                    err_level = (byte)(rec[8] & 0x03);
                    label29.Text = Convert.ToString(err_level);
                    switch (err_level)
                    {
                        case 0: label29.BackColor = Color.Lime; break;
                        case 1: label29.BackColor = Color.Red; break;
                        case 2: label29.BackColor = Color.Orange; break;
                        case 3: label29.BackColor = Color.Yellow; break;
                        default: break;
                    }
                }
                else if (rec[2] == 0x03)
                {
                    thermometer1.Value = rec[3];                        //控制器温度
                    thermometer2.Value = rec[4];                        //电池温度
                    ledBar2.Value = rec[5];                             //电池SOC
                    ledBar3.Value = rec[6];                             //电池SOH
                    sevenSegmentInteger1.Value = (rec[7]<<8) + rec[8];  //电池电压
                }
            }
            busy = false;
        }

        private void SearchAndAddSerialToComBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] MyString = new string[6];
            string Buffer;
            MyBox.Items.Clear();
            int count = 0;
            for (int i = 1; i < 9; i++)
            {
                try
                {
                    Buffer = "COM" + i.ToString();
                    MyPort.PortName = Buffer;
                    MyPort.Open();
                    MyString[count] = Buffer;
                    MyBox.Items.Add(Buffer);
                    MyPort.Close();
                    count++;
                }
                catch { }  
            }
            if (MyString[0] != null)
            {
                MyBox.Text = MyString[0];
                try
                {
                    MyPort.PortName = MyBox.Text;
                    MyPort.BaudRate = Convert.ToInt32(comboBox2.Text);
                    MyPort.Open();
                    button1.Text = "关闭串口";
                    led1.Value = false;
                }
                catch { }
            }
            else
            {
                button1.Text = "打开串口";
                led1.Value = true;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (serialPort1.IsOpen)
                {
                    close = true;
                    while (busy == true)
                        Application.DoEvents();
                    serialPort1.Close();
                    button1.Text = "打开串口";
                    led1.Value = true;
                   
                }
                else
                {
                    close = false;
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    serialPort1.Open();
                    button1.Text = "关闭串口";
                    led1.Value = false;
                }
            }
            catch
            {
                MessageBox.Show("打开串口失败！", "错误！");
            }
        }
        private void comboBox1_Click(object sender, EventArgs e)
        {
            string[] MyString = new string[6];
            string Buffer;
            int count = 0;
            comboBox1.Items.Clear();

            if (serialPort1.IsOpen == true)
            {
                close = true;
                while (busy == true)
                    Application.DoEvents();
                serialPort1.Close();
                button1.Text = "打开串口";
                led1.Value = true;
            }

            for (int i = 1; i < 9; i++)
            {
                try
                {
                    Buffer = "COM" + i.ToString();
                    serialPort1.PortName = Buffer;
                    serialPort1.Open();
                    MyString[count] = Buffer;
                    comboBox1.Items.Add(Buffer);
                    serialPort1.Close();
                    count++;
                }
                catch
                {
                }
            }
            comboBox1.Text = MyString[0];
        }

        //修改波特率
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
        }

        //修改停止位
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox3.Text.Equals("1"))
                serialPort1.StopBits = StopBits.One;
            else if (comboBox3.Text.Equals("1.5"))
                serialPort1.StopBits = StopBits.OnePointFive;
            else if (comboBox3.Text.Equals("2"))
                serialPort1.StopBits = StopBits.Two;
        }

        //修改数据位
        private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.DataBits = Convert.ToInt32(comboBox4.Text);
        }

        //修改奇偶校验
        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox5.Text.Equals("无"))
                serialPort1.Parity = Parity.None;
            else if (comboBox5.Text.Equals("奇校验"))
                serialPort1.Parity = Parity.Odd;
            else if (comboBox5.Text.Equals("偶校验"))
                serialPort1.Parity = Parity.Even;
        }
        private double getTime()
        {
            return (double)(DateTime.Now.Hour) / 24 + (double)(DateTime.Now.Minute) / 1440 + (double)(DateTime.Now.Second) / 86400 + (double)(DateTime.Now.Millisecond) / 86400000; 
        }




    }
}
